

#include "jxos_public.h"
#include "lib/ring_buff.h"

void (*s_byte_comm_send_byte_blocked_config_callback)(uint8_t send_byte) = 0;
uint8_t (*s_byte_comm_rec_byte_event_callback)(void) = 0;

#define REPEAT_TIMES		3

static RINGBUFF_MGR rec_buff;
static uint8_t rec_buff_space[REPEAT_TIMES];

static RINGBUFF_MGR send_buff;
static uint8_t send_buff_space[S_BYTE_COMM_SEND_BUFF_LEN];

static JXOS_EVENT_HANDLE send_event;

static swtime_type send_timer;
static swtime_type rec_timer;


static uint8_t verification(uint8_t* data)
{
	uint8_t i;
	uint8_t temp_data[REPEAT_TIMES];

	for(i = 0; i < REPEAT_TIMES; i++){
		ringbuff_read(&rec_buff, &(temp_data[i]));
	}
	
	for(i = 0; i < REPEAT_TIMES-1; i++){
		if(temp_data[i] != temp_data[i+1]){
			return 0;
		}
	}
	return 1;
}

uint8_t std_app_s_byte_comm_send(uint8_t send_byte)
{
	ringbuff_write(&send_buff, send_byte);
	jxos_event_set(send_event);
}

void std_app_s_byte_comm_rec_isr(uint8_t rec_byte)
{
	ringbuff_write(&rec_buff, rec_byte);
	sys_software_timer_task_restart_timer(rec_timer);
}


static void s_byte_comm_task(uint8_t task_id, void * parameter)
{
	uint8_t i;
	uint8_t temp_data;
	
	if(sys_software_timer_task_check_overtime_timer(rec_timer) == 1){
		sys_software_timer_task_stop_timer(rec_timer);
		if(verification(&temp_data) == 1){
			if(s_byte_comm_rec_byte_event_callback != 0){
				s_byte_comm_rec_byte_event_callback(temp_data);
			}
		}
	}
	
	if(sys_software_timer_task_check_overtime_timer(send_timer) == 1){
		sys_software_timer_task_stop_timer(send_timer);
	}
	
	if((sys_software_timer_task_check_running_timer(send_timer) == 0)
	&&(ringbuff_check_used_space(&send_buff) > 0)){
		if(jxos_event_wait(send_event) == 1){
			ringbuff_read(&send_buff, &temp_data);
			if(s_byte_comm_send_byte_blocked_config_callback != 0){
				for(i = 0; i < REPEAT_TIMES; i++){
					s_byte_comm_send_byte_blocked_config_callback(temp_data);
				}
			}
			sys_software_timer_task_restart_timer(send_timer);
		}
	}

}

void std_app_s_byte_comm_task_init(void)
{
	RingBuff(&rec_buff, REPEAT_TIMES, rec_buff_space);
	RingBuff(&send_buff, S_BYTE_COMM_SEND_BUFF_LEN, send_buff_space);
	
	send_event = jxos_event_create();
	jxos_task_create(s_byte_comm_task, "s_comm", 0);
	
	send_timer = sys_software_timer_task_new_timer();
	sys_software_timer_task_set_timer(send_timer, S_BYTE_COMM_INTERVAL_TIME_MS);
}